<script>
import { createEmojiElment } from '@/utils';
import { nextTick } from 'vue';

export default {
  props: {
    value: {
      type: String,
      default: ''
    },
    max: {
      type: Number,
      default: 300
    }
  },
  components: {
  },
  data() {
    return {
      rangeOfInputBox: null
    }
  },
  watch: {
    value: {
      async handler(newValue) {
        if (newValue !== this.convertToText(this.$refs.inputBox.innerHTML)) {
          await nextTick()
          this.$refs.inputBox.innerHTML = newValue
        }
      }
    }
  },
  mounted() {
    document.onselectionchange = () => {
      let selection = document.getSelection();

      if (selection.rangeCount > 0) {
        const range = selection.getRangeAt(0);

        if (this.$refs.inputBox.contains(range.commonAncestorContainer)) {
          this.rangeOfInputBox = range;
        }
      }
    };
  },
  beforeDestroy() {
    document.onselectionchange = null
  },
  methods: {
    handleBoxClick(event) {
      let target = event.target;
      this.setCaretForEmoji(target);
    },
    setCaretForEmoji(target) {
      if (target.tagName.toLowerCase() === "img") {
        let range = new Range();
        range.setStartBefore(target);
        range.collapse(true);
        document.getSelection().removeAllRanges();
        document.getSelection().addRange(range);
      }
    },
    calcContentLength() {
      return this.value.replace(/\[.*?\]/g, 'X').length
    },
    insertEmoji(name) {
      if (this.calcContentLength() >= this.max) return

      const emojiEl = createEmojiElment(name, true)

      if (!this.rangeOfInputBox) {
        this.rangeOfInputBox = new Range();
        this.rangeOfInputBox.selectNodeContents(this.$refs.inputBox);
      }

      if (this.rangeOfInputBox.collapsed) {
        this.rangeOfInputBox.insertNode(emojiEl);
      } else {
        this.rangeOfInputBox.deleteContents();
        this.rangeOfInputBox.insertNode(emojiEl);
      }
      this.rangeOfInputBox.collapse(false);

      this.handleConvertToText(this.$refs.inputBox.innerHTML)
    },
    handleConvertToText(richText) {
      // 正则匹配 <img src="/emoji/88_thumb.gif"> 替换为 [88_thumb]
      this.$emit('input', this.convertToText(richText))
    },
    convertToText(richText) {
      const emoji = createEmojiElment(null, false, true)
      const regx = new RegExp(emoji, 'g')
      return richText.replace(regx, '[$1]')
    },
    handleSend() {
      this.$emit('send')
    },
    handleLimit(e) {
      if (['Backspace', 'Del'].includes(e.key)) return
      if (this.calcContentLength() >= this.max) {
        e.preventDefault()
      }
    }
  },
}
</script>

<template>
  <div
    ref="inputBox"
    class="chat-input"
    contenteditable="inherit"
    @keydown="handleLimit"
    @keydown.enter.prevent="handleSend"
    @focus="$emit('focus')"
    @blur="$emit('blur')"
    @input="handleConvertToText($event.target.innerHTML)"
    @click="handleBoxClick"
  >
  </div>
</template>

<style lang="less" scoped>
.chat-input {
  outline: none;
  max-height: 100px;
  width: 100%;
  overflow-y: auto;
}
</style>
